package com.raincat.tools.notificationtools;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.os.Build;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 一个通用的Notification工具
 * <p>
 * Created by Administrator on 2018/3/29 0029.
 */

public class NotificationConfig {
    private NotificationManager mNotificationManager;
    private static NotificationConfig mNotificationConfig;

    public static NotificationConfig getInstance(Context context) {
        if (mNotificationConfig == null) {
            mNotificationConfig = new NotificationConfig(context);
        }
        return mNotificationConfig;
    }

    private NotificationConfig(Context context) {
        if (mNotificationManager == null)
            mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    }

    /**
     * 设置一个常驻通知栏的Notification，无进度条
     *
     * @param appId   标识符
     * @param ticker  通知首次出现在通知栏时提醒的文字
     * @param title   标题
     * @param content 详细内容
     * @param resId   通知栏的小图标
     */
    public void sendLockNotification(Context context, int appId, String ticker, String title, String content, int resId) {
        sendLockNotification(context, appId, ticker, title, content, resId, false, 0, 0);
    }

    /**
     * 设置一个常驻通知栏的Notification，带进度条
     *
     * @param appId          标识符
     * @param ticker         通知首次出现在通知栏时提醒的文字
     * @param title          标题
     * @param content        详细内容
     * @param isShowProgress 是否显示进度条
     * @param max            进度条满值
     * @param progress       进度条当前值
     */
    public void sendLockNotification(Context context, int appId, String ticker, String title, String content, int resId, boolean isShowProgress, int max, int progress) {
        NotificationCompat.Builder notification = new NotificationCompat.Builder(context);
        notification.setSmallIcon(resId);
        notification.setContentTitle(title);
        notification.setTicker(ticker);
        notification.setContentText(content);
        notification.setDefaults(Notification.DEFAULT_LIGHTS);

        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName() + appId, "通知", NotificationManager.IMPORTANCE_HIGH);
            notification.setChannelId(context.getPackageName() + appId);
            deleteNoNumberNotification(this.mNotificationManager, "通知");
            mNotificationManager.createNotificationChannel(notificationChannel);
        }

        if (isShowProgress)
            notification.setProgress(max, progress, false);
        /* 设置点击后通知不消失 */
        notification.setAutoCancel(false);
        //setOngoing(boolean)设为true,notification将无法通过左右滑动的方式清除，可用于添加常驻通知，必须调用cancel方法来清除
        notification.setOngoing(true);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, new Intent(), PendingIntent.FLAG_ONE_SHOT);
        notification.setContentIntent(pendingIntent);

        mNotificationManager.notify(appId, notification.build());
    }

    /**
     * 设置一个常驻通知栏的Notification，带进度条
     *
     * @param appId          标识符
     * @param ticker         通知首次出现在通知栏时提醒的文字
     * @param title          标题
     * @param content        详细内容
     * @param isShowProgress 是否显示进度条
     * @param max            进度条满值
     * @param progress       进度条当前值
     */
    public NotificationCompat.Builder getLockBuilder(Context context, int appId, String ticker, String title, String content, int resId, boolean isShowProgress, int max, int progress) {
        NotificationCompat.Builder notification = new NotificationCompat.Builder(context);
        notification.setSmallIcon(resId);
        notification.setContentTitle(title);
        notification.setTicker(ticker);
        notification.setContentText(content);
        notification.setDefaults(Notification.DEFAULT_LIGHTS);

        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName() + appId, "通知", NotificationManager.IMPORTANCE_HIGH);
            notification.setChannelId(context.getPackageName() + appId);
            deleteNoNumberNotification(this.mNotificationManager, "通知");
            mNotificationManager.createNotificationChannel(notificationChannel);
        }

        if (isShowProgress)
            notification.setProgress(max, progress, false);
        /* 设置点击后通知不消失 */
        notification.setAutoCancel(false);
        //setOngoing(boolean)设为true,notification将无法通过左右滑动的方式清除，可用于添加常驻通知，必须调用cancel方法来清除
        notification.setOngoing(true);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, new Intent(), PendingIntent.FLAG_ONE_SHOT);
        notification.setContentIntent(pendingIntent);
        return notification;
    }

    /**
     * 设置一个不常驻通知栏的Notification
     *
     * @param context
     * @param appId   标识符
     * @param ticker  通知首次出现在通知栏时提醒的文字
     * @param title   标题
     * @param content 详细内容
     */
    public void sendUnLockNotification(Context context, int appId, String ticker, String title, String content, int resId) {
        sendUnLockNotification(context, appId, true, true, ticker, title, content, resId, null, null);
    }

    /**
     * 设置一个不常驻通知栏的Notification
     *
     * @param appId     标识符
     * @param isVibrate 是否震动
     * @param isSound   是否发声
     * @param ticker    通知首次出现在通知栏时提醒的文字
     * @param title     标题
     * @param content   详细内容
     */
    public void sendUnLockNotification(Context context, int appId, boolean isVibrate, boolean isSound, String ticker, String title, String content, int resId) {
        sendUnLockNotification(context, appId, isVibrate, isSound, ticker, title, content, resId, null, null);
    }

    /**
     * 设置一个不常驻通知栏的Notification，带点击跳转效果
     *
     * @param appId     标识符
     * @param ticker    通知首次出现在通知栏时提醒的文字
     * @param title     标题
     * @param content   详细内容
     * @param className 需要跳转的Activity名字
     */
    public void sendUnLockNotification(Context context, int appId, String ticker, String title, String content, int resId, String className) {
        sendUnLockNotification(context, appId, true, true, ticker, title, content, resId, className, null);
    }

    /**
     * 设置一个不常驻通知栏的Notification，带点击跳转效果
     *
     * @param appId     标识符
     * @param isVibrate 是否震动
     * @param isSound   是否发声
     * @param ticker    通知首次出现在通知栏时提醒的文字
     * @param title     标题
     * @param content   详细内容
     * @param className 需要跳转的Activity名字
     */
    public void sendUnLockNotification(Context context, int appId, boolean isVibrate, boolean isSound, String ticker, String title, String content, int resId, String className) {
        sendUnLockNotification(context, appId, isVibrate, isSound, ticker, title, content, resId, className, null);
    }

    /**
     * 设置一个不常驻通知栏的Notification，带点击跳转效果，带传参
     *
     * @param appId     标识符
     * @param isVibrate 是否震动
     * @param isSound   是否发声
     * @param ticker    通知首次出现在通知栏时提醒的文字
     * @param title     标题
     * @param content   详细内容
     * @param className 需要跳转的Activity名字
     * @param param     往跳转的Activity传参
     */
    public void sendUnLockNotification(Context context, int appId, boolean isVibrate, boolean isSound, String ticker, String title, String content, int resId, String className, HashMap<String, String> param) {
        String warning = "记得把要跳转的Activity的launchMode设置成singleTask";
        NotificationCompat.Builder notification = new NotificationCompat.Builder(context);
        notification.setSmallIcon(resId);
        notification.setContentTitle(title);
        notification.setTicker(ticker);
        notification.setContentText(content);
        notification.setAutoCancel(true);
        notification.setDefaults(Notification.DEFAULT_LIGHTS);
        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName() + appId, "通知", NotificationManager.IMPORTANCE_HIGH);
            notification.setChannelId(context.getPackageName() + appId);
            notificationChannel.enableLights(true);
            notificationChannel.enableVibration(isVibrate);
            notificationChannel.setVibrationPattern(new long[]{200L, 200L, 200L, 200L});
            if (isSound) {
                notificationChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), Notification.AUDIO_ATTRIBUTES_DEFAULT);
            } else {
                notificationChannel.setSound(null, null);
            }

            deleteNoNumberNotification(this.mNotificationManager, "通知");
            mNotificationManager.createNotificationChannel(notificationChannel);
        } else {
            if (isVibrate) {
                notification.setVibrate(new long[]{200L, 200L, 200L, 200L});
            }

            if (isSound) {
                notification.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
            }
        }

        if (className != null) {
            Intent appIntent = new Intent(Intent.ACTION_MAIN);
            appIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            appIntent.setComponent(new ComponentName(context.getPackageName(), context.getPackageName() + "." + className));
            appIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
            if (param != null)
                for (Map.Entry<String, String> p : param.entrySet()) {
                    appIntent.putExtra(p.getKey(), p.getValue());
                }
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, appIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            notification.setContentIntent(pendingIntent);
        } else {
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, new Intent(), PendingIntent.FLAG_ONE_SHOT);
            notification.setContentIntent(pendingIntent);
        }

        this.mNotificationManager.notify(appId, notification.build());
    }

    @RequiresApi(api = 26)
    private void deleteNoNumberNotification(NotificationManager nm, String newChannelId) {
        List<NotificationChannel> notificationChannels = nm.getNotificationChannels();
        if (notificationChannels != null && notificationChannels.size() != 0) {

            for (NotificationChannel channel : notificationChannels) {
                if (channel.getId() != null && !channel.getId().equals(newChannelId)) {
                    int notificationNumbers = this.getNotificationNumbers(nm, channel.getId());
                    if (notificationNumbers == 0) {
                        nm.deleteNotificationChannel(channel.getId());
                    }
                }
            }

        }
    }

    @RequiresApi(api = 26)
    private int getNotificationNumbers(NotificationManager mNotificationManager, String channelId) {
        if (mNotificationManager != null && !TextUtils.isEmpty(channelId)) {
            int numbers = 0;
            StatusBarNotification[] activeNotifications = mNotificationManager.getActiveNotifications();
            int length = activeNotifications.length;

            for (StatusBarNotification item : activeNotifications) {
                Notification notification = item.getNotification();
                if (notification != null && channelId.equals(notification.getChannelId())) {
                    ++numbers;
                }
            }

            return numbers;
        } else {
            return -1;
        }
    }

    /**
     * 取消该通知
     *
     * @param appId 通知标识符
     */
    public void cancelNotification(int appId) {
        mNotificationManager.cancel(appId);
    }
}
